const axios = require('axios');
const cheerio = require('cheerio');
const fs = require('fs');
const path = require('path');
const download = require('image-downloader');
// ✅ 用自定义 delay 替代 require('delay')
function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
const { HttpsProxyAgent } = require('https-proxy-agent');
const puppeteer = require('puppeteer');

// 配置
const config = {
  requestDelay: 2000, // 2秒延迟
  maxRetries: 3, // 最大重试次数
  timeout: 10000, // 10秒超时
  userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
  proxies: [
    'http://proxy1.example.com:8080',
    'http://proxy2.example.com:8080'
  ], // 代理服务器列表
  outputDir: 'word_images'
};

// 图片源配置
const imageSources = {
  google: {
    name: 'Google',
    url: (word) => `https://www.google.com/search?q=${encodeURIComponent(word)}&tbm=isch`,
    parser: parseGoogleResults
  },
  bing: {
    name: 'Bing',
    url: (word) => `https://www.bing.com/images/search?q=${encodeURIComponent(word)}`,
    parser: parseBingResults
  },
  duckduckgo: {
    name: 'DuckDuckGo',
    url: (word) => `https://duckduckgo.com/?q=${encodeURIComponent(word)}&iax=images&ia=images`,
    parser: parseDuckDuckGoResults
  }
};

// 主函数
async function downloadWordImages(word, options = {}) {
  const {
    limit = 5,
    source = 'google',
    useProxy = false,
    useBrowser = false
  } = options;

  try {
    // 创建输出目录
    if (!fs.existsSync(config.outputDir)) {
      fs.mkdirSync(config.outputDir, { recursive: true });
    }

    console.log(`从${imageSources[source].name}搜索图片: "${word}"`);

    let imageUrls = [];

    if (useBrowser) {
      // 使用Puppeteer处理JavaScript渲染的页面
      imageUrls = await scrapeWithBrowser(word, source, limit);
    } else {
      // 普通HTTP请求
      const searchUrl = imageSources[source].url(word);
      const html = await fetchWithRetry(searchUrl, {
        useProxy,
        headers: { 'User-Agent': config.userAgent }
      });

      // 解析图片URL
      imageUrls = imageSources[source].parser(html, limit);
    }

    console.log(`找到 ${imageUrls.length} 张图片，开始下载...`);

    // 下载图片
    for (let i = 0; i < Math.min(imageUrls.length, limit); i++) {
      try {
        await downloadImage(word, imageUrls[i], i, { useProxy });
        await delay(config.requestDelay); // 请求延迟
      } catch (err) {
        console.error(`图片 ${i} 下载失败:`, err.message);
      }
    }

    console.log('下载完成！');
  } catch (error) {
    console.error('爬取过程中出错:', error.message);
  }
}

// 带重试和代理支持的请求
async function fetchWithRetry(url, options = {}, retryCount = 0) {
  try {
    const axiosOptions = {
      timeout: config.timeout,
      headers: options.headers || {}
    };

    // 使用代理
    if (options.useProxy && config.proxies.length > 0) {
      const proxy = config.proxies[retryCount % config.proxies.length];
      axiosOptions.httpsAgent = new HttpsProxyAgent(proxy);
      console.log(`使用代理: ${proxy}`);
    }

    const response = await axios.get(url, axiosOptions);
    return response.data;
  } catch (error) {
    if (retryCount < config.maxRetries) {
      console.log(`请求失败，第${retryCount + 1}次重试...`);
      await delay(config.requestDelay * (retryCount + 1)); // 延迟时间递增
      return fetchWithRetry(url, options, retryCount + 1);
    }
    throw new Error(`请求失败: ${error.message}`);
  }
}

// 下载单张图片
async function downloadImage(word, imgUrl, index, options = {}) {
  try {
    const extension = path.extname(imgUrl.split('?')[0]) || '.jpg';
    const filename = `${word}_${index}_${Date.now()}${extension}`;
    const outputPath = path.join(config.outputDir, filename);

    const downloadOptions = {
      url: imgUrl,
      dest: outputPath,
      timeout: config.timeout
    };

    if (options.useProxy && config.proxies.length > 0) {
      const proxy = config.proxies[index % config.proxies.length];
      downloadOptions.agent = new HttpsProxyAgent(proxy);
    }

    await download.image(downloadOptions);
    console.log(`下载成功: ${filename}`);
  } catch (error) {
    throw new Error(`图片下载失败: ${error.message}`);
  }
}

// 使用Puppeteer处理JS渲染的页面
async function scrapeWithBrowser(word, source, limit) {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();
  await page.setUserAgent(config.userAgent);

  try {
    const searchUrl = imageSources[source].url(word);
    await page.goto(searchUrl, { waitUntil: 'networkidle2', timeout: config.timeout });

    // 等待图片加载
    await page.waitForSelector('img', { timeout: config.timeout });
    await delay(2000); // 额外等待2秒

    // 获取页面内容
    const html = await page.content();
    await browser.close();

    return imageSources[source].parser(html, limit);
  } catch (error) {
    await browser.close();
    throw error;
  }
}

// 各图片源的解析器
function parseGoogleResults(html, limit) {
  const $ = cheerio.load(html);
  const imageUrls = [];

  $('img').each((i, element) => {
    if (i < limit) {
      const imgUrl = $(element).attr('src') || $(element).attr('data-src');
      if (imgUrl && imgUrl.startsWith('http')) {
        imageUrls.push(imgUrl);
      }
    }
  });

  return imageUrls;
}

function parseBingResults(html, limit) {
  const $ = cheerio.load(html);
  const imageUrls = [];

  $('.mimg').each((i, element) => {
    if (i < limit) {
      const imgUrl = $(element).attr('src') || $(element).attr('data-src');
      if (imgUrl && imgUrl.startsWith('http')) {
        imageUrls.push(imgUrl);
      }
    }
  });

  return imageUrls;
}

function parseDuckDuckGoResults(html, limit) {
  const $ = cheerio.load(html);
  const imageUrls = [];

  $('.tile--img__img').each((i, element) => {
    if (i < limit) {
      const imgUrl = $(element).attr('src') || $(element).attr('data-src');
      if (imgUrl && !imgUrl.startsWith('data:')) {
        imageUrls.push(`https:${imgUrl}`);
      }
    }
  });

  return imageUrls;
}

// 使用示例
(async () => {
  // 从Google下载，不使用代理
  // await downloadWordImages('apple', { limit: 3, source: 'google' });

  // 从Bing下载，使用代理
  // await downloadWordImages('banana', { limit: 2, source: 'bing', useProxy: true });

  // 从DuckDuckGo下载，使用浏览器渲染
  await downloadWordImages('hello', { limit: 4, source: 'duckduckgo', useBrowser: true });
})();